#include <cstdint>
#include <cstring>
#include <ostream>
#include <sstream>
#include <string>
#include <unistd.h>
#include "Logger.h"
#if __cplusplus >= 201402L
#    include "LoggerNew.h"
#endif

int main(int argc, const char** argv)
{
#if __cplusplus >= 201402L
    xncc::Logger::start();
    // log no args
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message no args");
    // log bool args
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with bool args %d %d %d", true, false, true);
    // log bool varible args
    bool x = true;
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with bool args %d %d %d", x, !x, x);

    // log int number args lietral or variable
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with int number args %d %d", 1, 2);
    int16_t a = -1;
    int32_t b = -2;
    int64_t c = -3;
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with mulit int number args %d %d %d", a, b, c);

    // log unsigned int number args lietral or variable
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with unsigned int number args %u %u %u", 1u, 2u, 3u);
    uint16_t d = 1;
    uint32_t e = 2;
    uint64_t f = 3;
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with mulit unsigned int number args %u %u %u", d, e, f);

    // log hex number args
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with hex number args %x %x %x", 1, 2, 3);

    // log hex number variable args
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with hex number args %x %x %x", d, e, f);

    // log float number args lietral or variable
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with float number args %f %f %f", 1.0f, 2.0f, 3.0f);
    float g = 1.0f;
    float h = 2.0f;
    float i = 3.0f;
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with mulit float number args %f %f %f", g, h, i);

    // log double number args lietral or variable
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with double number args %f %f %f", 1.0, 2.0, 3.0);
    double j = 1.0;
    double k = 2.0;
    double l = 3.0;
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with mulit double number args %f %f %f", j, k, l);

    // log char args
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with char args %c %c %c", 'a', 'b', 'c');
    char m = 'a';
    char n = 'b';
    char o = 'c';
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with mulit char args %c %c %c", m, n, o);

    // log unsigned char args
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with unsigned char args %c %c %c", 'a', 'b', 'c');
    unsigned char p = 'a';
    unsigned char q = 'b';
    unsigned char r = 'c';
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with mulit unsigned char args %c %c %c", p, q, r);

    // log string args
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with string args %s %s %s", "axxxxx", "bxxxxx", "cxxxxx");
    std::string s = "axxxxx";
    std::string t = "bxxxxx";
    std::string u = "cxxxxx";
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with mulit string args %s %s %s", s.c_str(), t.c_str(),
                   u.c_str());

    // log constant string args
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with constant string args %S %S %S", "axxxxx"_s, "bxxxxx"_s,
                   "cxxxxx"_s);

    // log percent sign args
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with percent sign args %% %% %%");

    // log ptr args
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with ptr args %p %p %p", &a, &b, &c);

    // log function args
    struct TrivalObj
    {
        int  a;
        int  b;
        int  c;
        void ToString(std::ostringstream& oss)
        {
            oss << " member function a=" << a << " b=" << b << " c=" << c << " ";
        }
    };

    TrivalObj obj;
    obj.a = 1;
    obj.b = 2;
    obj.c = 3;
    XNCC_LOG_DEBUG(CONSOLE_LOG, "this is a log message with function args %F %F %F",
                   xncc::FUNCTION_OBJECT(obj, &TrivalObj::ToString), xncc::FUNCTION_OBJECT(obj, &TrivalObj::ToString),
                   xncc::FUNCTION_OBJECT(obj, &TrivalObj::ToString));

    // log only data log
    {
        // log no args
        XNCC_LOG(CONSOLE_LOG, "this is a log message no args");

        // log int number args lietral or variable
        XNCC_LOG(CONSOLE_LOG, "this is a log message with int number args %d %d", 1, 2);
        int16_t a = -1;
        int32_t b = -2;
        int64_t c = -3;
        XNCC_LOG(CONSOLE_LOG, "this is a log message with mulit int number args %d %d %d", a, b, c);

        // log unsigned int number args lietral or variable
        XNCC_LOG(CONSOLE_LOG, "this is a log message with unsigned int number args %u %u %u", 1u, 2u, 3u);
        uint16_t d = 1;
        uint32_t e = 2;
        uint64_t f = 3;
        XNCC_LOG(CONSOLE_LOG, "this is a log message with mulit unsigned int number args %u %u %u", d, e, f);

        XNCC_LOG(CONSOLE_LOG, "this is a log message with mulit unsigned int number args %x %x %x", d, e, f);
        // log float number args lietral or variable
        XNCC_LOG(CONSOLE_LOG, "this is a log message with float number args %f %f %f", 1.0f, 2.0f, 3.0f);
        float g = 1.0f;
        float h = 2.0f;
        float i = 3.0f;
        XNCC_LOG(CONSOLE_LOG, "this is a log message with mulit float number args %f %f %f", g, h, i);

        // log double number args lietral or variable
        XNCC_LOG(CONSOLE_LOG, "this is a log message with double number args %f %f %f", 1.0, 2.0, 3.0);
        double j = 1.0;
        double k = 2.0;
        double l = 3.0;
        XNCC_LOG(CONSOLE_LOG, "this is a log message with mulit double number args %f %f %f", j, k, l);

        // log char args
        XNCC_LOG(CONSOLE_LOG, "this is a log message with char args %c %c %c", 'a', 'b', 'c');
        char m = 'a';
        char n = 'b';
        char o = 'c';
        XNCC_LOG(CONSOLE_LOG, "this is a log message with mulit char args %c %c %c", m, n, o);

        // log unsigned char args
        XNCC_LOG(CONSOLE_LOG, "this is a log message with unsigned char args %c %c %c", 'a', 'b', 'c');
        unsigned char p = 'a';
        unsigned char q = 'b';
        unsigned char r = 'c';
        XNCC_LOG(CONSOLE_LOG, "this is a log message with mulit unsigned char args %c %c %c", p, q, r);

        // log string args
        XNCC_LOG(CONSOLE_LOG, "this is a log message with string args %s %s %s", "axxxxx", "bxxxxx", "cxxxxx");
        std::string s = "axxxxx";
        std::string t = "bxxxxx";
        std::string u = "cxxxxx";
        XNCC_LOG(CONSOLE_LOG, "this is a log message with mulit string args %s %s %s", s.c_str(), t.c_str(), u.c_str());

        char buffer[4]         = "abc";
        char test_buffer[1024] = {0};
        memcpy(test_buffer, buffer, 4);
        XNCC_LOG(CONSOLE_LOG, "this is a log message with string buffer args %s", test_buffer);

        // log constant string args
        XNCC_LOG(CONSOLE_LOG, "this is a log message with constant string args %S %S %S", "axxxxx"_s, "bxxxxx"_s,
                 "cxxxxx"_s);

        // log percent sign args
        XNCC_LOG(CONSOLE_LOG, "this is a log message with percent sign args %% %% %%");

        // log ptr args
        XNCC_LOG(CONSOLE_LOG, "this is a log message with ptr args %p %p %p", &a, &b, &c);

        // log function args
        struct TrivalObj
        {
            int  a;
            int  b;
            int  c;
            void ToString(std::ostringstream& oss)
            {
                oss << " member function a=" << a << " b=" << b << " c=" << c << " ";
            }
        };

        TrivalObj obj;
        obj.a = 1;
        obj.b = 2;
        obj.c = 3;
        XNCC_LOG(CONSOLE_LOG, "this is a log message with function args %F %F %F",
                 xncc::FUNCTION_OBJECT(obj, &TrivalObj::ToString), xncc::FUNCTION_OBJECT(obj, &TrivalObj::ToString),
                 xncc::FUNCTION_OBJECT(obj, &TrivalObj::ToString));
    }

#endif
    return 0;
}